--[[
Constants
Defaults used throughout the game
--]]
KENO_VERSION  = "0.1a"
KENO_TITLE    = "Keno " .. KENO_VERSION
KENO_LOGO     = "balls/keno.png"
BALL_BLUE     = "balls/blueball.png"
BALL_RED      = "balls/redball1.png"
BG_BLUE       = "balls/bg_blue.png"
BG_RED        = "balls/bg_red.png"
BG_GREEN      = "balls/bg.png"
HISTORY       = love.filesystem.getSaveDirectory( ).."/history.tbl"

--[[
DO NOT MODIFY BELOW THIS LINE
This is the game code. Changing this could break all my hard work :)
--]]
require("tablesave-094")

Keno = {}
Keno.__index = Keno

function Keno.create()
   printf("[ %s ]\n", KENO_TITLE)
   local game = {}
   setmetatable(game,Keno)
   game.headstailsgap = 5
   game.ballpos = {}
   game.board = {}
   game.current = {}
   game.history = {}
   game.logoup = false
   game.running = false
   game.scalex = .7
   game.scaley = .7
   game.num = 0
   return game
end

function Keno:initialise()
  printf("- Initialising..\n")
  self:checkhistoryfile()
  math.randomseed(os.time())
  self:loadImages()
  -- Ball images
  balls = {["red"]={self.images.ballred, self.images.ballred:getWidth(), self.images.ballred:getHeight()},
           ["blue"]={self.images.ballblue, self.images.ballblue:getWidth(), self.images.ballblue:getHeight()}}

   	-- Load balls
  self:loadBallPositions()
  self:loadBallBackground()
  self.x = self.board.width/2
  self.y = self.board.height/2
  self:resetgame()
  self.running = true
end

function Keno:checkhistoryfile()
  printf("- History file exists.. ")
  love.filesystem.mkdir( "1" )
  fHistory = love.filesystem.exists("history.tbl")
  print(fHistory)  
  if fHistory then
    printf(" - Loading history.. ")
    self.history = table.load( HISTORY )
    print("OK")
  else
    printf("- Creating history file.. ")
    local tHistory = {}
    tHistory.games = 0
    tHistory.balls = {}
    for iX=1,80 do
      tHistory.balls[iX] = 0
    end
    assert( table.save( tHistory, HISTORY ) == 1 )  
    print("OK")
    printf(" - Loading history.. ")
    self.history = table.load( HISTORY )
    print("OK")
  end
end

function Keno:resetgame()
  self.running = false
  self.current.ballinplay = false
  self.current.ball = {}
  self.current.numbers = {}
  self.current.called = {}
  self.current.heads = 0
  self.current.tails = 0
  self.sprites.bbred:clear()
  self.sprites.bbblue:clear()
end

function Keno:startgame()
  self:resetgame()
  self:loadNumbers()
  self.history.games = self.history.games + 1
  self.running = true
end

function Keno:loadImages()
  self.images = {}
  self.sprites = {}
  self.images.logo = love.graphics.newImage(KENO_LOGO)   
  self.images.bbgreen = love.graphics.newImage(BG_GREEN)
  self.images.bbblue = love.graphics.newImage(BG_BLUE) 
  self.images.bbred = love.graphics.newImage(BG_RED)
  self.images.ballred = love.graphics.newImage(BALL_RED)
  self.images.ballblue = love.graphics.newImage(BALL_BLUE)
  self.sprites.bbred = love.graphics.newSpriteBatch(self.images.bbred, 80)  
  self.sprites.bbblue = love.graphics.newSpriteBatch(self.images.bbblue, 80)
  self.sprites.bbgreen = love.graphics.newSpriteBatch(self.images.bbgreen, 80)   
end

function Keno:fadeLogo()
  local pause = 0
  local pstart = love.timer.getTime()
  for iAlpha = 0,255 do
    while pause < 100 do
      p = love.timer.getTime()
      pause = pause + (p - pstart)
    end
      print(iAlpha)
      love.graphics.setColor(255,255,255,iAlpha)
      love.graphics.draw(self.logo, 0, 0)
      pstart = love.timer.getTime()
      pause = 0
  end
--  	self.running = true
end

--[[
function Keno:loadBallBackground()
Load the default background that the balls land on
--]]
function Keno:loadBallBackground()
  printf("- Loading ball background... ")
  self.board.height = self.headstailsgap
  self.board.width = 0
  local iGap = 0
  local imgBg = self.images.bbgreen

  for iX = 1,10 do
    for iY = 1,8 do
      if iY > 4 then
        iGap = self.headstailsgap
      end
      self.sprites.bbgreen:add((iX*imgBg:getWidth())-imgBg:getWidth(), (iY*imgBg:getHeight())-imgBg:getHeight()+iGap)
      if iX == 1 then self.board.height = self.board.height + imgBg:getHeight() end
      if iY == 1 then self.board.width = self.board.width + imgBg:getWidth() end
    end
    iGap = 0
  end
  
  self.board.swidth = self.board.width*self.scaley
  self.board.sheight = self.board.height*self.scalex 
  printf("OK\n")
  printf("-- Board Height: %s\n", self.board.height)
  printf("-- Board Width: %s\n", self.board.width)
  printf("-- Board Height (scaled): %s\n", self.board.sheight)
  printf("-- Board Width (scaled): %s\n", self.board.swidth)
end

--[[
function Keno:loadBallPositions()
Load the default ball positions
This is based on the size of the ball backgrounds created in Keno:loadBallBackground()
--]]
function Keno:loadBallPositions()
  printf("- Loading ball positions... ")
  local iGap = 0
  local imgBg = self.images.bbgreen

  for iY = 1, 8 do
    for iX = 1, 10 do
      if iY > 4 then iGap = self.headstailsgap end
      x = (iX*imgBg:getWidth()) - (imgBg:getWidth()/2)
      y = (iY*imgBg:getHeight()) - (imgBg:getHeight()/2) + iGap
      table.insert(self.ballpos, {x, y})
    end
    iGap = 0
  end
  printf("OK\n")
end

--[[
function Keno:loadNumbers()
Load the ball numbers (1-80) into a table
--]]
function Keno:loadNumbers()
  printf("- Loading numbers... ")
  for iNum = 1, 80 do
    table.insert(self.current.numbers, iNum)
  end
  math.random(); math.random(); math.random()
  printf("OK\n")
end

--[[
function Keno:picknumbers()
Pick a random number from the table "numbers" created in Keno:loadNumbers()
--]]
function Keno:picknumber()
  local iNum = math.random(#self.current.numbers)
  local iBallNum = self.current.numbers[iNum]
  table.remove(self.current.numbers, iNum)
  return iBallNum
end

function Keno:spawn_ball(pos, scale, scalerate, direction)
  printf("Spawning ball: %s\n", pos)
  self.current.ball.ballnum = pos
  self.current.ball.x = self.ballpos[pos][1]
  self.current.ball.y = self.ballpos[pos][2]
  self.current.ball.nx = self.current.ball.x
  self.current.ball.ny = self.current.ball.y
  self.current.ball.scale = scale
  self.current.ball.scalerate = scalerate
  self.current.ball.direction = direction
  self.current.ball.fWidth = bfont:getWidth(pos)/2
  self.current.ball.fHeight = bfont:getHeight(pos)/2
  self.current.ball.htadded = false
  self.current.ballinplay = true
end

function Keno:gameStop()
  self.running = false
end

function Keno:getscalerate(c)
  self.current.ball.speed = self:getmovelength(self.current.ball) / 60
  self.current.ball.scalerate = .02
end

function Keno:getmovelength(ball)
    if self.current.ball.direction == "up" then
      vx = self.x - self.current.ball.x
      vy = self.y - self.current.ball.y
    else
      vx = self.current.ball.nx - self.current.ball.x
      vy = self.current.ball.ny - self.current.ball.y
    end
	length = math.sqrt(vx * vx + vy * vy)
  return length
end

--[[
function kenoball:up()
Moves the keno ball from the bottom of the screen into the center
--]]
function Keno:moveball()
    if self.current.ball.direction ~= "stopped" then
    if pstart ~= nil then
      p = love.timer.getTime()
      pause = pause + p-pstart
      if self.current.ball.htadded == false then
        if self.current.ball.ballnum < 41 then
          self.current.heads = self.current.heads + 1
        else
          self.current.tails = self.current.tails + 1
        end
        self.current.ball.htadded = true
      end
    else pause = 1000 end
    if pause > 5 then
    pstart = nil
    if self.current.ball.direction == "up" then
      vx = self.x - self.current.ball.x
      vy = self.y - self.current.ball.y
    else
      vx = self.current.ball.nx - self.current.ball.x
      vy = self.current.ball.ny - self.current.ball.y
    end
	
    
    if self.current.ball.scalerate == 0 then
      self:getscalerate(self.current.ball)
    end

    length = math.sqrt(vx * vx + vy * vy)
    
    if (math.floor(length) <= 5) then
      if (self.current.ball.direction == "up") then
        self.current.ball.direction = "down"
        self.current.ball.scalerate = 0
        pstart = love.timer.getTime()
        pause = 0
      else
        self.current.ball.direction = "stopped"
        self.current.ballinplay = false;
        self.current.ball.scale = .20
        self.current.ball.x = self.current.ball.nx
        self.current.ball.y = self.current.ball.ny
        table.insert(self.current.called, { ballnum = self.current.ball.ballnum, x = self.current.ball.x, y = self.current.ball.y })
        if self.current.ball.ballnum < 41 then
          bb = self.sprites.bbred
        else
          bb = self.sprites.bbblue
        end
        bb:add(self.current.ball.x-(self.images.bbgreen:getWidth()/2), self.current.ball.y-(self.images.bbgreen:getHeight()/2))
      end
    end

    if self.current.ballinplay then
    if (math.floor(length) > 5) then
      if (self.current.ball.direction == "up") then
        vx = vx / length
        vy = vy / length
        self.current.ball.x = self.current.ball.x + vx * self.current.ball.speed
        self.current.ball.y = self.current.ball.y + vy * self.current.ball.speed
        self.current.ball.scale = self.current.ball.scale + self.current.ball.scalerate
      end

      if (self.current.ball.direction == "down") then
        vx = vx / length
        vy = vy / length
        self.current.ball.x = self.current.ball.x + vx * self.current.ball.speed
        self.current.ball.y = self.current.ball.y + vy * self.current.ball.speed
        self.current.ball.scale = self.current.ball.scale - self.current.ball.scalerate
      end
    end
    end
    end
    end
    return self.current.ballinplay
end

function getpoint(point, x0, y0, x1, y1, i)		 
  if point == "x" then		 
    result = ((y1 - i)*x0 + (i - y0)*x1) / (y1 - y0)		 
  else		 
    result = ((x1 - i)*y0 + (i - x0)*y1) / (x1 - x0)		 
  end		 
  return result		 
end

function Keno:drawbox(coords, colour, iWidth)		 
  local iWidth = iWidth or 15
  local outline = coords
		 
  local y1 = getpoint("y", outline[1], outline[2], outline[7], outline[8], outline[1])--+iWidth)		 
  local x2 = getpoint("x", outline[3], outline[4], outline[5], outline[6], y1)		 
		 
  local filling = {outline[1]+iWidth,outline[2]+iWidth,		 
                   outline[3]-iWidth,outline[4]+iWidth,		 
                   outline[5]-iWidth,outline[6]-iWidth,		 
                   outline[7]+iWidth,outline[8]-iWidth		 
                  }
                  
  love.graphics.setColor(255, 255, 255)		 
  love.graphics.polygon('fill', outline)		 
  love.graphics.setColor(colour)		 
  love.graphics.polygon('fill', filling)		 
  love.graphics.setColor(255, 255, 255)	
end

function Keno:drawBoard()
    -- Translate to the bottom center of window
    local x = ((love.graphics.getWidth()-self.board.swidth)/self.scalex)/2
    local y = ((love.graphics.getHeight()-self.board.sheight)/self.scaley)-self.headstailsgap
    love.graphics.translate(x, y)

    -- Draw the board background with red/blue overlay
    love.graphics.draw(self.sprites.bbgreen, 0, 0)
    love.graphics.draw(self.sprites.bbred, 0, 0)
    love.graphics.draw(self.sprites.bbblue, 0, 0)

    -- Draw the balls numbers that have been called
    if #self.current.called > 0 then
      for k, c in ipairs(self.current.called) do
      love.graphics.print(c.ballnum, c.x-(bfont:getWidth(c.ballnum)/2*.3), c.y-(bfont:getHeight(c.ballnum)/2*.3), 0, .3, .3)
      end
    end
end

function Keno:process()
  if self.running and self.current.ballinplay == false and #self.current.numbers > 60 then
    local iBallNum = self:picknumber()
    self:spawn_ball(iBallNum, .20, 0, "up")
    self.history.balls[iBallNum] = self.history.balls[iBallNum] + 1
  end
  
  if self.running and #self.current.numbers == 60 then
    --print("finished")
    --assert( table.save( self.history, HISTORY ) == 1 )  
  end
  
  
  if self.current.ballinplay then
    local ballfinished = not self:moveball()
    if ballfinished and #self.current.numbers == 60 then
      print "- Game finished."
      assert( table.save( self.history, HISTORY ) == 1 )
      self:startgame()      
    end
  end
end

function Keno:drawheadstails(heads, tails)
  love.graphics.push()
  love.graphics.translate(380, 60)
  self:drawbox({0, 0, 230, 0, 250, 120, 20, 120}, {231, 65, 65}, 13)
  local textWidth = bfont:getWidth(heads)*.3
  local textHeight = bfont:getHeight(heads)*.3
  local textX = (250/2)-(textWidth/2)
  local textY = (120/2)-(textHeight/2)
  love.graphics.print(heads, textX, textY, 0, .3, .3)
  love.graphics.pop()

  love.graphics.push()
  love.graphics.translate(590, 60)
  self:drawbox({0, 0, 250, 0, 230, 120, 20, 120}, {49, 86, 172}, 13)
  local textWidth = bfont:getWidth(tails)*.3
  local textHeight = bfont:getHeight(tails)*.3
  local textX = (250/2)-(textWidth/2)
  local textY = (120/2)-(textHeight/2)
  love.graphics.print(tails, textX, textY, 0, .3, .3)
  love.graphics.pop()
end

function Keno:drawgamenumber(iNum)		 
  love.graphics.push()
  love.graphics.translate(1150, 60)
  self:drawbox({0, 0, 300, 0, 280, 115, 30, 120}, {49, 86, 172}, 13)
  local textWidth = bfont:getWidth(iNum)*.3
  local textHeight = bfont:getHeight(iNum)*.3
  local textX = (310/2)-(textWidth/2)
  local textY = (110/2)-(textHeight/2)
  love.graphics.print(iNum, textX, textY, 0, .3, .3)
  love.graphics.pop()  
end


function Keno:render()
  if self.running then
    love.graphics.setBackgroundColor(74, 148, 74);
    self:drawbox({-10,-10,love.graphics.getWidth()+10,-10,love.graphics.getWidth()+10,110,-10,90}, {102,255,255}, 4)

    love.graphics.scale(self.scalex,self.scaley)
    
    -- Draw the game board with color overlays and called numbers
    self:drawgamenumber(self.history.games)
    self:drawheadstails(self.current.heads, self.current.tails)
  
    love.graphics.push()
    self:drawBoard()
    if self.current.ballinplay == true then
      if self.current.ball.ballnum < 41 then myball = balls["red"] else myball = balls["blue"] end
      love.graphics.draw(myball[1], self.current.ball.x, self.current.ball.y, 0, self.current.ball.scale, self.current.ball.scale, myball[2]/2, myball[3]/2)
      scale = self.current.ball.scale
      love.graphics.print(self.current.ball.ballnum, self.current.ball.x-(self.current.ball.fWidth*scale), self.current.ball.y-(self.current.ball.fHeight*scale), 0, scale, scale)
    end
    love.graphics.pop()
  end
end




